package com.example.dw.controller;

import com.example.dw.common.Result;
import com.example.dw.dto.*;
import com.example.dw.entity.*;
import com.example.dw.service.ExamService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

/**
 * 考试控制器
 * @author system
 * @since 2024-01-01
 */
@Slf4j
@RestController
@RequestMapping("/exam")
@Tag(name = "考试管理", description = "考试相关的API接口")
public class ExamController {

    @Autowired
    private ExamService examService;

    /**
     * 生成考试
     */
    @PostMapping
    @Operation(summary = "生成考试", description = "根据用户ID和考试生成参数生成考试")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "考试生成成功"),
            @ApiResponse(responseCode = "400", description = "请求参数错误"),
            @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public Result<Map<String, Object>> generateExam(HttpServletRequest request,
                                                     @Validated @RequestBody ExamGenerateDTO generateDTO) {
        try {
            Integer userid = getCurrentUserId(request);
            Map<String, Object> result = examService.generateExam(userid, generateDTO);
            return Result.success(result);
        } catch (Exception e) {
            log.error("生成考试失败：{}", e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 对比答案
     */
    @PostMapping("/compare")
    @Operation(summary = "对比答案", description = "根据用户ID和答案对比参数对比答案")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "答案对比成功"),
            @ApiResponse(responseCode = "400", description = "请求参数错误"),
            @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public Result<Map<String, Object>> compareAnswer(HttpServletRequest request,
                                                      @Validated @RequestBody AnswerCompareDTO compareDTO) {
        try {
            Integer userid = getCurrentUserId(request);
            Map<String, Object> result = examService.compareAnswer(userid, compareDTO);
            return Result.success(result);
        } catch (Exception e) {
            log.error("对比答案失败：{}", e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 提交试卷
     */
    @PostMapping("/submit")
    @Operation(summary = "提交试卷", description = "根据用户ID和试卷提交参数提交试卷")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "试卷提交成功"),
            @ApiResponse(responseCode = "400", description = "请求参数错误"),
            @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public Result<Map<String, Object>> submitExam(HttpServletRequest request,
                                                   @Validated @RequestBody ExamSubmitDTO submitDTO) {
        try {
            Integer userid = getCurrentUserId(request);
            Map<String, Object> result = examService.submitExam(userid, submitDTO);
            return Result.success(result);
        } catch (Exception e) {
            log.error("提交试卷失败：{}", e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 获取所有试卷
     */
    @GetMapping("/examAll")
    @Operation(summary = "获取所有试卷", description = "根据用户ID获取所有试卷")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "获取试卷成功"),
            @ApiResponse(responseCode = "400", description = "请求参数错误"),
            @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public Result<List<UserExam>> getAllExams(HttpServletRequest request) {
        try {
            Integer userid = getCurrentUserId(request);
            List<UserExam> exams = examService.getAllExams(userid);
            return Result.success(exams);
        } catch (Exception e) {
            log.error("获取所有试卷失败：{}", e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 获取未完成试卷
     */
    @GetMapping("/examUnfinished")
    @Operation(summary = "获取未完成试卷", description = "根据用户ID获取未完成试卷")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "获取未完成试卷成功"),
            @ApiResponse(responseCode = "400", description = "请求参数错误"),
            @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public Result<List<UserExam>> getUnfinishedExam(HttpServletRequest request) {
        try {
            Integer userid = getCurrentUserId(request);
            List<UserExam> exams = examService.getUnfinishedExam(userid);
            return Result.success(exams);
        } catch (Exception e) {
            log.error("获取未完成试卷失败：{}", e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 根据试卷id获取试卷
     */
    @GetMapping("/{examid}")
    @Operation(summary = "根据试卷id获取试卷", description = "根据试卷ID获取试卷详情")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "获取试卷成功"),
            @ApiResponse(responseCode = "400", description = "请求参数错误"),
            @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public Result<Map<String, Object>> getExamById(HttpServletRequest request,
                                                    @PathVariable Integer examid) {
        try {
            Integer userid = getCurrentUserId(request);
            Map<String, Object> result = examService.getExamById(userid, examid);
            return Result.success(result);
        } catch (Exception e) {
            log.error("根据试卷id获取试卷失败：{}", e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 根据课程类型id获取试卷
     */
    @GetMapping("/examCourseType/{courseTypeid}")
    @Operation(summary = "根据课程类型id获取试卷", description = "根据课程类型ID获取试卷列表")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "获取试卷成功"),
            @ApiResponse(responseCode = "400", description = "请求参数错误"),
            @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public Result<List<Exam>> getExamByCourseType(HttpServletRequest request,
                                                   @PathVariable Integer courseTypeid) {
        try {
            Integer userid = getCurrentUserId(request);
            List<Exam> exams = examService.getExamByCourseType(courseTypeid);
            return Result.success(exams);
        } catch (Exception e) {
            log.error("根据课程类型id获取试卷失败：{}", e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 是否能生成考试
     */
    @PostMapping("/jugdExam")
    @Operation(summary = "判断是否能生成考试", description = "根据用户ID和考试生成参数判断是否能生成考试")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "判断成功"),
            @ApiResponse(responseCode = "400", description = "请求参数错误"),
            @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public Result<Map<String, Object>> judgeGenerateExam(HttpServletRequest request,
                                                          @Validated @RequestBody ExamGenerateDTO generateDTO) {
        try {
            Integer userid = getCurrentUserId(request);
            Map<String, Object> result = examService.judgeGenerateExam(userid, generateDTO);
            return Result.success(result);
        } catch (Exception e) {
            log.error("判断是否能生成考试失败：{}", e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 根据课程类型id获取试卷分页
     */
    @PostMapping("/examCourseType")
    @Operation(summary = "根据课程类型id获取试卷分页", description = "根据课程类型ID和查询参数获取试卷分页")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "获取试卷分页成功"),
            @ApiResponse(responseCode = "400", description = "请求参数错误"),
            @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public Result<Map<String, Object>> getExamByCourseTypePage(HttpServletRequest request,
                                                                @RequestBody ExamQueryDTO queryDTO) {
        try {
            Integer userid = getCurrentUserId(request);
            Map<String, Object> result = examService.getExamByCourseTypePage(userid, queryDTO);
            return Result.success(result);
        } catch (Exception e) {
            log.error("根据课程类型id获取试卷分页失败：{}", e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 根据类型获取未完成试卷
     */
    @PostMapping("/examUnfinishedByType")
    @Operation(summary = "根据类型获取未完成试卷", description = "根据课程类型ID和查询参数获取未完成试卷")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "获取未完成试卷成功"),
            @ApiResponse(responseCode = "400", description = "请求参数错误"),
            @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public Result<List<UserExam>> getUnfinishedExamByCourseType(HttpServletRequest request,
                                                                 @RequestBody ExamQueryDTO queryDTO) {
        try {
            Integer userid = getCurrentUserId(request);
            List<UserExam> exams = examService.getUnfinishedExamByCourseType(userid, queryDTO.getCourseTypeid());
            return Result.success(exams);
        } catch (Exception e) {
            log.error("根据类型获取未完成试卷失败：{}", e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 从请求中获取当前用户ID
     */
    private Integer getCurrentUserId(HttpServletRequest request) {
        Integer userid = (Integer) request.getAttribute("userid");
        if (userid == null) {
            throw new RuntimeException("未授权访问");
        }
        return userid;
    }
} 